Skip to content

Removed hard-coded logic for electrolyzer replacement schedule#555

Open
elenya-grant wants to merge 9 commits intoNatLabRockies:developfrom
elenya-grant:all_tech_refurb
Open

Removed hard-coded logic for electrolyzer replacement schedule#555
elenya-grant wants to merge 9 commits intoNatLabRockies:developfrom
elenya-grant:all_tech_refurb

Conversation

@elenya-grant
Copy link
Collaborator

@elenya-grant elenya-grant commented Feb 26, 2026

Removed hard-coded logic for electrolyzer replacement schedule

Removed the hard-coded logic within the finance models and H2IntegrateModel that was specific to connecting the replacement schedule from the technology to a finance model if a technology name included "electrolyzer". Now - the replacement schedule is passed to the finance models for all technologies.

Note: This is ready for an in-depth review, but I have noted some specific questions for reviewers in Section 2 under "Type of Reviewer Feedback Requested"

Since technology-specific finance models do not expect the electrolyzer replacement schedule to be connected, there is some added logic to handle tech-specific finance models (before, the logic was not explicit and relied on whether the commodity_stream for a finance subgroup was None. This logic has been replaced with more explicit logic. Additionally, since this logic is handled/defined at the subgroup-level, it is not possible to have a finance subgroup that includes finance_groups that have a mix of technology-specific and finance specific models (this has always been the case). Further information on this is described in Section 5. But - I added in an error message to catch this case if it were to pop up.

This also required updating the feedstock cost model to output a replacement schedule. An alternative to adding this output to the feedstock cost model would be to add in logic to connect_technologies that checks if 'feedstock' is in the technology name (this alternative approach was the route taken for transport technologies).

I also added a documentation page about the technology naming convention in H2I to communicate what naming convention is requires so that the logic within H2I functions as expected.

Section 1: Type of Contribution

  • Feature Enhancement
    • Framework
    • New Model
    • Updated Model
    • Tools/Utilities
    • Other (please describe):
  • Bug Fix
  • Documentation Update
  • CI Changes
  • Other (please describe):

Section 2: Draft PR Checklist

  • Open draft PR
  • Describe the feature that will be added
  • Fill out TODO list steps
  • Describe requested feedback from reviewers on draft PR
  • [-] Complete Section 7: New Model Checklist (if applicable)

TODO

  • Add test that error is thrown if combining technology-specific finance model and system-level finance model in a finance subgroup.

Type of Reviewer Feedback Requested (on Draft PR)

Structural feedback:

Implementation feedback:

  • Should the feedstock cost model have an output of replacement_schedule or should we introduce logic into connect_technologies so that technologies with feedstock in the name do not have the replacement schedule passed to the finance model? This logic would maybe have to be duplicated in the finance models if so. I like the current implementation since it reduces the amount of naming-specific logic in the code base.
  • Similar question to above, but relating to the transport models. The logic for the transport model is to not connect the replacement schedule to the finance model if "transport" is in the tech name. Since theres only two transport models that can be defined in the tech config, this felt like the best way to do it (rather than add replacement_schedule as an output to both transport models).

Other feedback:

  • Should the naming convention for the electricity producing techs and the naming convention for default commodities streams (defined in the default_techs_to_commodities dictionary in H2IntegrateModel.create_finance_model()) be described in the docs/user_guide/expected_naming_convention.md doc page?

Section 3: General PR Checklist

  • PR description thoroughly describes the new feature, bug fix, etc.
  • Added tests for new functionality or bug fixes
  • Tests pass (If not, and this is expected, please elaborate in the Section 6: Test Results)
  • Documentation
    • Docstrings are up-to-date
    • Related docs/ files are up-to-date, or added when necessary
    • Documentation has been rebuilt successfully
    • [-] Examples have been updated (if applicable)
  • CHANGELOG.md has been updated to describe the changes made in this PR

Section 3: Related Issues

This is somewhat related to Issue #485

Section 4: Impacted Areas of the Software

Section 4.1: New Files

  • docs/user_guide/expected_naming_convention.md: new doc page that explains what naming convention is needed for technologies in H2I so that it functions properly

Section 4.2: Modified Files

  • h2integrate/finances/profast_base.py - ProFastBase: removed logic around electrolyzer replacement schedule, added input for all replacement schedule for all technologies, and updated replacement schedule calculation to use inputs['replacement_schedule_{tech}'] instead of time between replacement.
  • examples/08_wind_electrolyzer/user_finance_model/simple_lco.py: added input of technology replacement schedules
  • h2integrate/finances/numpy_financial_npv.py - NumpyFinancialNPV: removed logic around electrolyzer replacement schedule, added input for all replacement schedule for all technologies, and updated replacement schedule calculation to use inputs['replacement_schedule_{tech}'] instead of time between replacement.
  • h2integrate/core/feedstocks.py: added replacement_schedule output to FeedstockCostModel
  • h2integrate/core/h2integrate_model.py:
    • create_finance_model():
      • added system_finance_model key to the finance_subgroups dictionary. This is a boolean that is True if the finance model is system-level and False if the finance model is tech-specific.
      • added a counter variable n_tech_finances_in_group that is equal to the number of technology-specific finance models within a finance subgroup. This is used so that later on, we can throw an error message if someone has a mix of technology-specific finance models and system-level finance models within one finance subgroup.
    • connect_technologies()
      • Removed elif statement for elif "storage" in source_tech and elif "storage" in dest_tech because it was the same logic that is done in the else statement and was therefore unnecessary.
      • Connecting techs to finance models: Replaced logic of if commodity_stream is not None to if is_system_finance_model which is pulled from the finance_subgroups attribute that is created in create_finance_model()
      • Connecting techs to finance models: Added logic when looping through technologies to connect technology replacement schedule to the finance model if is_system_finance_model is True and tech_name does not include "transport".
      • Connecting techs to finance models: Added a check if the technology is 'cable' or 'pipe' since those are protected transport item names. This change was not necessary for this PR, but if someone had put 'cable' or 'pipe' in the technologies for a finance subgroup, there would've been an error (but now there won't be an error! yay!)
  • h2integrate/core/test/test_framework.py: added new test, test_invalid_finance_group_combination, for error message added

Section 5: Additional Supporting Information

it is not possible to have a finance subgroup that includes finance_groups that have a mix of technology-specific and finance specific models.

Suppose we have a technology-specific finance model for the steel technology and a system-level finance model named profast_model (as is the case in Example 1). If a user tried to run both of these finance models as shown below:

finance_subgroups:
  steel:
    commodity: steel
    finance_groups: ['steel', 'profast_model']
    technologies: [steel]

there would be an error (this PR now includes a more verbose error than the error that would've occurred when trying to run H2I).

The user should instead define two finance subgroups, one per finance model.

finance_subgroups:
  steel:
    commodity: steel
    finance_groups: ['steel']
    technologies: [steel]
  steel_profast:
    commodity: steel
    finance_groups: ['profast_model']
    technologies: [steel]

This error does not come up if finance models defined in the finance_groups for a specific finance subgroup are either all tech-specific finance models OR all system-level finance models (see example 8).

Section 6: Test Results, if applicable

@elenya-grant elenya-grant added framework finance Items specifically related to financial models ready for review This PR is ready for input from folks labels Feb 26, 2026
Copy link
Collaborator

@jaredthomas68 jaredthomas68 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks pretty good to me. Thanks for continuing to generalize and reduce tech-specific logic. My main thoughts are as follows:

  1. Let's allow for costs for transport techs (needed in current project)
  2. I don't love having costs or replacement schedule in feedstocks, but if the user does not need to do anything with them then I think it is ok if keeps things more general.

Copy link
Collaborator

@jaredthomas68 jaredthomas68 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

finance Items specifically related to financial models framework ready for review This PR is ready for input from folks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants